$(document).ready(function(){
	Nav.playBanner();
	Fundr.recordIP();
	Fund.activateFavorites();
	// initiate datepickers
	$("input[validate*=date]").each(function(){
		$(this).datepicker();
	});
	
	//initiate slimscroll
	$(function(){
	    $('#layout-filters-scrolling').slimScroll({
	        height: 'auto',
	        color: '#888888',
	        railColor:'#999999',
	        alwaysVisible:false,
	        railVisible:true
	    });
	});
	
	Scroll.init();
	//autoscroll filters
	$(window).scroll(function(){
		Scroll.adjustFixedOrRelative();
		Scroll.adjustVisibleScrollArea();
		Scroll.adjustSlimScroll();
		Fund.throttle(Modal.reposition,'reposition',170);
	});
	$(window).resize(function(){
		Scroll.adjustFixedOrRelative();
		Scroll.adjustVisibleScrollArea();
		Scroll.adjustSlimScroll();
		Fund.throttle(Modal.reposition,'reposition',170);
	});
	
	// listen for html injection
	$(document).bind('document:changed',function(event){
		//console.warn('html injected');
		$("input[validate*=date]").datepicker();
		$("input,textarea").filter(function() { // filter will exclude anything in the hidden_forms div
		    return $(this).closest(".hidden_forms").length == 0;
		}).placeholder();
		Bubble.init();
	});
	
	// listen for logged in
	$(document).bind('user:login',function(event){
		//console.warn('login triggered');
		Nav.showLoggedin();
		var $payment_method_td = $('td.payment_method_td');
		var date = new Date();
		Cookie.set('lastLoggedIn',date.getMonth() + '/' + date.getDate() + '/' + date.getFullYear(),90);
		if(Fund.awaitingLogin){
			Modal.open('create_fund_form');
		}
		if($payment_method_td.length == 0){
			Fund.query();
		}
		Fund.reloadPaymentMethods();
		Login.checkSession();
	});
	
	// listen for logged out
	$(document).bind('user:logout',function(event){
		//console.warn('logout in triggered');
	});
		
	$(document).trigger('document:changed');
	Fundr.loadingSrc = $('#loadingGIF').attr('src');
});

Fundr = {
	assetRoot:"/assets/media/",
	root:"/cfcs/remote.cfc?",
	ajaxURL:function(cfc,method){
		return Ajax.url(cfc,method);
	},
	getInput:function(name){
		var result = $('input[name='+name+']').val() || "";
		return result;
	},
	getSelect:function(name){
		var result = $('select[name='+name+']').val() || "";
		return result;
	},
	getAjaxData:function($area){
		var data = {};
		$area.find('input,select').not('[type=checkbox],[type=radio]').each(function(){
			if($(this).closest(".hidden_forms").length == 0){
				data[this.name] = $(this).val() || "";
			}
		});
		$area.find('input[type=checkbox]').each(function(){
			if($(this).is(':checked') && $(this).closest(".hidden_forms").length == 0){
				data[this.name] = $(this).val() || "";
			}
		});
		$area.find('input[type=radio]').each(function(){
			var $this = $(this);
			if($this.closest(".hidden_forms").length == 0){
				if(!(this.name in data)){
					data[this.name] = "";
				}
				if($this.is(':checked')){
					data[this.name] = $this.val();
				}
			}
		});
		$area.find('textarea').each(function(){
			if($(this).closest(".hidden_forms").length == 0){
				data[this.name] = $(this).val() || "";
			}
		});
		return data;
	},
	imgURL:function(path){
		return Fundr.assetRoot + path;
	},
	recordIP:function(){
		setTimeout(function(){
			Ajax.run("sessionService.recordClientIP",
				function(data){/*do nothing */},
				{ip:clientIP}
			);
		},1500);
	},
	getLoadingIcon:function(style,id){
		style = style || "";
		id = id || "";
		return "<img src='"+ Fundr.loadingSrc + "' style='"+style+"' id='"+id+"' />";
	}
};

Modal = {
	$:[],
	$container:[],
	forms:{}, // store entered values for any form here.
	isOpen:function(){
		var result = false;
		if($('#pp_full_res').length > 0){
			result = true;
		}
		return result;
	},
	open:function(id){
		var wait = 0;
		if(Modal.isOpen()){
			Modal.close();
			wait = 350;
		}
		
		var focus = Modal.setting[id].focus;
		var height = Modal.setting[id].height;
		var width = Modal.setting[id].width;
		
		Modal.settings.changepicturecallback = function(){
			Modal.$ = $('#pp_full_res'); // set the $'d modal here
			Modal.$container = $('.pp_default'); // set the $'d modal container here
			
			Modal.restoreContents(); // look for saved content and restore it
			$('.pp_overlay').click(function(){Modal.close();}); // close the modal when click outside of it.
			$('.pp_content').css('height','0px');
			// calculate height numbers
			var ymod = (height - 34) / 2; 
			var top = +$('.pp_default').css('top').split('px')[0];
			
			// calculate width numbers
			var xmod = (width-174) / 2;
			var left = +$('.pp_default').css('left').split('px')[0];
			
			$('.pp_default').css('top',top-ymod+'px'); // set top
			$('.pp_default').css('left',left-xmod+'px'); // set left
			$('.pp_content').css('width',width + 'px'); // set width

			if(focus != ""){
				$("div.pp_content").find('[name='+focus+']').focus(); // focus
			}
			
			var key = $('#pp_full_res').find('div.filterSet-title').attr("id");
			key = key.substring(7,key.length);
			if(key in Modal.callback){
				Modal.callback[key]();
			}
			
			Modal.reposition(0);
			
			$(document).trigger('document:changed');
		};
		
		setTimeout(function(){
			$.prettyPhoto.open('#'+id,Modal.settings);
			// trigger document changed
			$(document).trigger('document:changed');
		},wait);
	},
	close:function(){
		Modal.saveContents();
		$.prettyPhoto.close();
	},
	saveContents:function(){
		var formID = $("#pp_full_res").find('.filterSet-title').attr('id');
		var formName = formID.substring(7,formID.length);
		Modal.forms[formName] = Fundr.getAjaxData($('div#pp_full_res'));
	},
	restoreContents:function(){
		var $modal = $('#pp_full_res');
		var formID = $modal.find('.filterSet-title').attr('id');
		var formName = formID.substring(7,formID.length);
		if(formName in Modal.forms){
			for(key in Modal.forms[formName]){
				var $input = $modal.find('[name='+key+']');
				if($input.length > 0 && $input.attr('type') != 'file'){
					if($input.attr('type') == "radio"){
						Radio.set(key,Modal.forms[formName][key]);
					} else {
						$input.val(Modal.forms[formName][key]);
					}
				}
			}
		}
	},
	setting:{},
	settings:{
		social_tools:false,
		opacity:.5,
		default_width:175,
		keyboard_shortcuts:false,
		default_height:400,
		allow_resize:false,
		show_title:false,
		modal:true // modal has to be programmtically closed;
	},
	init:function(id,focus,height,width){
		Modal.setting[id] = {};
		Modal.setting[id].focus = focus;
		Modal.setting[id].height = height;
		Modal.setting[id].width = width;
	},
	callback:{},
	getPosition:function(){
		Modal.windowHeight = $(window).height();
		Modal.windowWidth = $(window).width();
		Modal.modalHeight = Modal.$.children().children().height();
		Modal.modalWidth = Modal.$.children().children().width();
	},
	windowHeight:0,
	windowWidth:0,
	modalHeight:0,
	modalWidth:0,
	reposition:function(time){
		if(Modal.isOpen()){
			if(time != 0){
				time = time || 200;
			}
			Modal.getPosition();

			var left = Math.round((Modal.windowWidth - Modal.modalWidth)/2);
			var top = Math.round((Modal.windowHeight - Modal.modalHeight)/2) + $(window).scrollTop();
			if(time == 0){
				Modal.$container.css('left',left+'px');
				Modal.$container.css('top',top+'px');
			} else {
				Modal.$container.animate({'left':left+'px','top':top+'px'},time);
			}
		}
	}
};

Alert = {
	getSystemMessages:function(){
		$.ajax({
			url:Fundr.ajaxURL("alertService","getMessages"),
			type:"POST",
			success:function(data){
				var alert = "";
				for(var i = 0; i < data.length; i++){
					if(i > 0){alert += "</br>";	}
					alert += data[i];
				}
				if(alert != ""){
					//Alert.showMessage(alert);
				}
			}
		});
	},
	showValidation: function(message,left){
		var jFocused = $("*:focus");
		// Alert.validationMessages.dialog('close');
		var vert = $(window).height() / 2;
		if(jFocused.length == 1){
			var scrollTop = $(document).scrollTop();
			var offset = jFocused.offset().top;
			vert = offset - scrollTop - 40;
		}
		var showLeft = left || false;
		Alert.validationMessages.empty();
		Alert.validationMessages.html("<span class='validation'>"+message+"</span>");
		var width = ($(window).width() / 2);
		if(showLeft){
			width -= 626;
			Alert.validationMessages.dialog("option","show",{effect:"drop",direction:"right"});
		} else {
			width += 620;
			Alert.validationMessages.dialog("option","show",{effect:"drop",direction:"left"});
		}
		Alert.validationMessages.dialog("option","position",[width,vert]);
		Alert.validationMessages.dialog('open');
	},
	showMessage: function(message,left){
		// Alert.systemMessages.dialog('close');
		var showLeft = left || false;
		Alert.systemMessages.empty();
		Alert.systemMessages.html("<span class='instructions'>"+message+"</span>");
		var width = ($(window).width() / 2);
		if(showLeft){
			width -= 596;
			Alert.systemMessages.dialog("option","show",{effect:"drop",direction:"right"});
		} else {
			width += 520;
			Alert.systemMessages.dialog("option","show",{effect:"drop",direction:"left"});
		}
		var vert = ($(window).height() / 2) - 120;
		Alert.systemMessages.dialog("option","position",[width,vert]);
		Alert.systemMessages.dialog('open');
	}
};

var Cookie = {
	set:function(name,value,days){
		if (days) {
			var date = new Date();
			date.setTime(date.getTime()+(days*24*60*60*1000));
			var expires = "; expires="+date.toGMTString();
		}
		else var expires = "";
		document.cookie = name+"="+value+expires+"; path=/";
	},
	get:function(name){
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for(var i=0;i < ca.length;i++) {
			var c = ca[i];
			while (c.charAt(0)==' ') c = c.substring(1,c.length);
			if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
		}
		return "";
	},
	remove:function(name){
		Cookie.set(name,"",-1);
	}
};

var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{
			string: navigator.userAgent,
			subString: "Chrome",
			identity: "Chrome"
		},
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari",
			versionSearch: "Version"
		},
		{
			prop: window.opera,
			identity: "Opera",
			versionSearch: "Version"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			   string: navigator.userAgent,
			   subString: "iPhone",
			   identity: "iPhone/iPod"
	    },
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]
};

var Radio = {
	set:function(name,value){
		var currentValue = Radio.get(name);
		var $radio = $('input[type=radio][name='+name+'][value='+value+']');
		if(Modal.isOpen()){
			var $radio = $('#pp_full_res').find('input[type=radio][name='+name+'][value='+value+']');
		}
		$radio.prop('checked',true);
		if(currentValue != value){
			$radio.change();
		}
		Radio.reflect(name);
	},
	get:function(name){
		var $radio = $('input[type=radio][name='+name+']:checked');
		if(Modal.isOpen()){
			$radio = $('#pp_full_res').find('input[type=radio][name='+name+']:checked');
		}
		var value = $radio.val() || "";
		
		return value;
	},
	getOptionName:function(name){ // returns the name of the option instead of the value (which may be uuid)
		var value = Radio.get(name);
		var text = $('ul#radio_'+name).find('input[value='+value+']').attr('title');
		return text;
	},
	reflect:function(name){
		var $radios = $('ul#radio_'+name);
		if(Modal.isOpen()){
			$radios = $('#pp_full_res').find('ul#radio_'+name);;
		}
		$radios.find('li').removeClass('selected');
		var value = Radio.get(name);
		$radios.find('li[value='+value+']').addClass('selected');
	},
};

var Checkbox = {
	toggle:function(that){
		var $checkbox = $(that).find('input[type=checkbox]');
		if($checkbox.is(':checked')){
			Checkbox.uncheck($checkbox,that);
		} else {
			Checkbox.check($checkbox,that);
		}
		Checkbox.reflect($checkbox,that);
	},
	check:function($checkbox,that){
		$checkbox.prop('checked',true);
	},
	uncheck:function($checkbox,that){
		$checkbox.prop('checked',false);
	},
	reflect:function($checkbox,that){
		if($checkbox.prop('checked') == true){
			$(that).addClass('checked');
		} else {
			$(that).removeClass('checked');
		}
		$checkbox.change();
	},
	get:function(name){
		var $checkboxes = $('#checkboxes_'+name);
		var result = "";
		$checkboxes.find('input:checked').each(function(){
			if(result != ""){
				result+=",";
			}
			result+= this.value;
		});
		return result;
	},
	set:function(name,values,nochange){
		var nochange = nochange || false;
		var $checkboxes = $('#checkboxes_'+name);
		values = ','+values+',';
		$checkboxes.find('li').each(function(){
			var $this = $(this);
			var thisValue = ','+$this.attr('value')+',';
			if(values.indexOf(thisValue) >= 0){
				$this.addClass('checked');
				$this.find('input').prop('checked',true);
			} else {
				$this.removeClass('checked');
				$this.find('input').prop('checked',false);
			}
			console.log(nochange);
			if(!nochange){
				$this.find('input').change();
			}
		});
	}
};

var TriRadio = {
	toggle:function(that){
		var $that = $(that);
		var number = +$that.attr('count');
		if(number == 3){
			number = 0;
		}
		number++;
		$that.addClass('hidden');
		var $nextLi = $that.parent().find('li[count='+number+']');
		$nextLi.removeClass('hidden');
		$nextLi.find('input').prop('checked',true);
		$nextLi.find('input').change();
	},
	set:function(name,value,nochange){
		var value = value || "";
		var nochange = nochange || false;
		var $triRadio = $('#triRadio_'+name);
		$triRadio.find('li').addClass("hidden");
		var $option = $triRadio.find('li[value='+value+']');
		$option.removeClass('hidden');
		$option.find("input").prop('checked',true);
		$triRadio.find('li[value='+value+']').removeClass('hidden');
		if(!nochange){
			$option.change();
		}
	}
};

var Bubble = {
	me:[],
	busy:false,
	init:function(){
		Bubble.me = $('.chat-bubble');
		$('[bubble]').off('hover');
		$('[bubble]').hover(function(){
			if(!Bubble.busy && (Cookie.get('HELP') == 'true' || this.id == 'help-toggle')){
				var text = $(this).attr('bubble');
				$('#bubble-text').html(text);
				Bubble.busy = true;
				Bubble.me.fadeIn(100,function(){
					Bubble.busy = false;
				});
			}
		},function(){
			Bubble.me.fadeOut(100);
		});
		$(document).bind('mousemove',function(e){
			var height = Bubble.me.height();
			Bubble.me.css({left:e.pageX-22,top:e.pageY-(height+36)});
		});
	},
	toggle:function(){
		var $this = $('#help-toggle');
		if(Cookie.get('HELP') == 'true'){
			Cookie.set('HELP','false');
			$this.html('Help: Off');
			Bubble.busy = true;
			Bubble.me.fadeOut(100,function(){
				Bubble.busy = false;
				$this.attr('bubble','Hover over items to see help text.</br>(Click to turn on)');
			});
		} else {
			Cookie.set('HELP','true');
			$this.html('Help: On');
			Bubble.me.fadeOut(100,function(){
				Bubble.busy = false;
				$this.attr('bubble','Hover over items to see help text.</br>(Click to turn off)');
			});
		}
	}
};

var Filter = {
	busy:{}, // tracks which filters are animating.
	toggle:function(filterID){
		var $up = $('#'+filterID+'_up');
		var $down = $('#'+filterID+'_down');
		var $filterSet = $('#filterSet_'+filterID);
		var $filterSetTitle = $('#filter_'+filterID);
		if($up.css('display') == 'none'){
			$up.show();
			$down.hide();
			$filterSetTitle.css('borderRadius','4px 4px 0px 0px');
			$filterSet.slideDown(function(){
			});
		} else{
			$up.hide();
			$down.show();
			$filterSet.slideUp(function(){
				$filterSetTitle.css('borderRadius','4px');
			});
		}
	}
};

var Scroll = {
	init:function(){
		Scroll.$banner = $("#layout-messages");
		Scroll.$filters = $("#layout-filters-scrolling");
		Scroll.$promo = $("#layout-promo-scrolling");
		Scroll.headerHeight = $('#layout-navigation').height();
		Scroll.$filtersParent = Scroll.$filters.parent();
		Scroll.$promoParent = Scroll.$promo.parent();
		Scroll.adjustVisibleScrollArea();
		Scroll.$filters.scrollTop('0');
	},
	footerHeight:20,
	headerHeight:0,
	$header:[],
	$banner:[],
	$filters:[],
	$filtersParent:[],
	$promo:[],
	$promoParent:[],
	adjustFixedOrRelative:function(){
		var bannerHeight = Scroll._getBannerHeight();
		var scrollTop = $(document).scrollTop();
		var $slim = Scroll.$filters.parent();
		var $slimScrollBar
		if(scrollTop - bannerHeight > 0){
			Scroll.$filters.css('position','fixed');
			Scroll.$filters.css('top','56px');
			Scroll.$filters.css('zIndex','1');
			Scroll.$promo.css('position','fixed');
			Scroll.$promo.css('top','56px');
			$slim.css('position','fixed');
			$slim.css('top','56px');
			$slim.css('width','174px');
			$slim.css('zIndex','1');
		} else {
			Scroll.$filters.css('top','0px');
			Scroll.$filters.css('zIndex','1');
			Scroll.$filters.css('position','relative');
			Scroll.$promo.css('top','0px');
			Scroll.$promo.css('position','relative');
			$slim.css('position','relative');
			$slim.css('top','0px');
			$slim.css('width','auto');
			$slim.css('zIndex','1');
		}
	},
	adjustVisibleScrollArea:function(){
		var bannerHeight = Scroll._getBannerVisibleHeight();
		var windowHeight = $(window).height();
		var useableHeight = windowHeight - Scroll.footerHeight - Scroll.headerHeight - bannerHeight;
		Scroll.$filters.height(useableHeight);
		Scroll.$filtersParent.height(useableHeight);
	},
	_getBannerHeight:function(){
		var bannerHeight = Scroll.$banner.height();
		if(!Scroll.$banner.is(':visible')){
			bannerHeight = 0;
		}
		return bannerHeight;
	},
	_getBannerVisibleHeight:function(){
		var bannerHeight = Scroll._getBannerHeight();
		bannerHeight = bannerHeight - $(window).scrollTop(); 
		if(bannerHeight < 0){
			bannerHeight = 0;
		}
		return bannerHeight
	},
	adjustSlimScroll:function(){
		// resize the scrollable area for slimscroll
		var height = $('#layout-filters-scrolling').height();
		$('.slimScrollDiv').height(height);
		$('#layout-filters-scrolling').height(height-7);
	}
};

Object.size = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};